home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 129_01.zip / 210ROOMB.C < prev    next >
Text File  |  1993-06-01  |  20KB  |  705 lines

  1. /************************************************************************/
  2. /*                roomb.c                 */
  3. /*        room code for Citadel bulletin board system        */
  4. /************************************************************************/
  5.  
  6. /************************************************************************/
  7. /*                History                 */
  8. /*                                    */
  9. /* 84Dec28 HAW    indexRooms modified to list deleted rooms.        */
  10. /* 84Dec20 JLS    renameRoom changed aides can decide to cause amnesia.    */
  11. /* 84Dec20 JLS & HAW "vp" union eliminated from the system.        */
  12. /* 84Jun28 JLS    Enhancement: Creator of a room is listed in Aide>.    */
  13. /* 84Jun23 HAW & JLS  Local unused variables are zapped.        */
  14. /* 84Jun10 JLS    Room cannot have a name of length 0.            */
  15. /* 84May07 JLS & HAW Fix bug in makeRoom to ensure correct g. # inc.ed. */
  16. /* 84Apr04 HAW    Start upgrade to BDS 1.50a.                */
  17. /* 83Feb26 CrT    bug in makeRoom when out of rooms fixed.        */
  18. /* 83Feb26 CrT    matchString made caseless, normalizeString()        */
  19. /* 83Feb26 CrT    "]" directory prompt, user name before prompts        */
  20. /* 82Dec06 CrT    2.00 release.                        */
  21. /* 82Nov02 CrT    Cleanup prior to V1.2 mods.                */
  22. /* 82Nov01 CrT    Proofread for CUG distribution.             */
  23. /* 82Mar27 dvm    conversion to v. 1.4 begun                */
  24. /* 82Mar25 dvm    conversion for TRS-80/Omikron test started        */
  25. /* 81Dec21 CrT    Log file...                        */
  26. /* 81Dec20 CrT    Messages...                        */
  27. /* 81Dec19 CrT    Rooms seem to be working...                */
  28. /* 81Dec12 CrT    Started.                        */
  29. /************************************************************************/
  30.  
  31. #include <210ctdl.h>
  32.  
  33. /************************************************************************/
  34. /*                Contents                */
  35. /*                                    */
  36. /*    editText()        handles the end-of-message-entry menu    */
  37. /*    findRoom()        find a free room            */
  38. /*    getNumber()        prompt user for a number, limited range */
  39. /*    getRoom()        load given room into RAM        */
  40. /*    getString()        read a string in from user        */
  41. /*    getText()        reads a message in from user        */
  42. /*    getYesNo()        prompts for a yes/no response        */
  43. /*    givePrompt()        gives usual "THISROOM>" prompt        */
  44. /*    indexRooms()        build RAM index to ctdlroom.sys     */
  45. /*    makeRoom()        make new room via user dialogue     */
  46. /*    matchString()        search for given string         */
  47. /*    noteRoom()        enter room into RAM index        */
  48. /*    putRoom()        store room to given disk slot        */
  49. /*    renameRoom()        sysop special to rename rooms        */
  50. /*    replaceString()     string-substitute for message entry    */
  51. /*    zapRoomFile()        erase & re-initialize ctdlroom.sys    */
  52. /************************************************************************/
  53.  
  54. /************************************************************************/
  55. /*    editText() handles the end-of-message-entry menu.        */
  56. /*    return TRUE  to save message to disk,                */
  57. /*           FALSE to abort message, and                */
  58. /*           ERROR if user decides to continue            */
  59. /************************************************************************/
  60. int editText(buf, lim)
  61. char *buf;
  62. int lim;
  63. {
  64.     char iChar(), toUpper()/*, buff[BUFSIZ]*/;
  65. /*
  66. int count;
  67.  
  68.     count = 25; */
  69.     do {
  70.     outFlag = OUTOK;
  71.     mPrintf("\n entry cmd: ");
  72.     switch (toUpper(iChar())) {
  73.     case 'A':
  74.         mPrintf("bort\n ");
  75.         if (getYesNo(" confirm")) return FALSE;
  76.         break;
  77.     case 'C':
  78.         mPrintf("ontinue\n ");
  79.         return ERROR;
  80.     case 'P':
  81.         mPrintf("rint formatted\n ");
  82.         doCR();
  83.         mPrintf(   "   ");
  84.         printDate();
  85.         if (loggedIn)   mPrintf(" from %s", msgBuf.mbauth);
  86.         doCR();
  87.         mFormat(buf);
  88.         break;
  89.     case 'R':
  90.         mPrintf("eplace string\n ");
  91.         replaceString(buf, lim);
  92.         break;
  93.     case 'S':
  94.         mPrintf("ave buffer\n ");
  95.         return TRUE;
  96.     default:
  97.         tutorial("edit.mnu");
  98. /*count--;*/
  99.         break;
  100.     }
  101.     } while ((haveCarrier  ||  onConsole)/* && count*/);
  102. /*if (count == 0) {
  103.     fcreat("blasted", buff);
  104.     fprintf(buff, "%s\nhC=%d, oC=%d, jLC=%d, Ooops=%d\nnC=%d, wIO=%d\032",
  105. logBuf.lbname,
  106.         haveCarrier, onConsole, justLostCarrier, Ooops, newCarrier,
  107.     whichIO);
  108.     fclose(buff);
  109.     onConsole = FALSE;
  110.     haveCarrier = interpret(pCarrDetect);
  111.     justLostCarrier = !haveCarrier;
  112. }*/
  113.     return FALSE;
  114. }
  115.  
  116. /************************************************************************/
  117. /*    findRoom() returns # of free room if possible, else ERROR    */
  118. /************************************************************************/
  119. int findRoom()
  120. {
  121.     int roomRover;
  122.  
  123.     for (roomRover=0;  roomRover<MAXROOMS;  roomRover++) {
  124.     if (!(roomTab[roomRover].rtflags & INUSE)) return roomRover;
  125.     }
  126.     return ERROR;
  127. }
  128.  
  129. /************************************************************************/
  130. /*    getNumber() prompts for a number in (bottom, top) range.    */
  131. /************************************************************************/
  132. int getNumber(prompt, bottom, top)
  133. char   *prompt;
  134. unsigned bottom;
  135. unsigned top;
  136. {
  137.     unsigned try;
  138.     char numstring[NAMESIZE];
  139.  
  140.     do {
  141.     outFlag = OUTOK;
  142.     getString(prompt, numstring, NAMESIZE);
  143.     try    = atoi(numstring);
  144.     if (try < bottom)  mPrintf("Sorry, must be at least %d\n", bottom);
  145.     if (try > top    )  mPrintf("Sorry, must be no more than %d\n", top);
  146.     } while ((try < bottom ||  try > top)
  147.       && (haveCarrier  ||  onConsole)
  148.     );
  149.     return  try;
  150. }
  151.  
  152. /************************************************************************/
  153. /*    getRoom()                            */
  154. /************************************************************************/
  155. getRoom(rm)
  156. int rm;
  157. {
  158.     int      read();
  159.     unsigned val;
  160.  
  161.     /* load room #rm into memory starting at buf */
  162.     thisRoom    = rm;
  163.     seek(roomfl, rm*SECSPERROOM, 0);
  164.     if ((val = read(roomfl, &roomBuf, SECSPERROOM)) >= 1000)   {
  165.     printf(" ?getRoom(): read failed, val=%d\n", val);
  166.     }
  167.     crypte(&roomBuf, (SECSPERROOM * SECTSIZE), rm);
  168. }
  169.  
  170. /************************************************************************/
  171. /*    getString() gets a string from the user.            */
  172. /************************************************************************/
  173. getString(prompt, buf, lim)
  174. char *prompt;
  175. char *buf;
  176. int  lim;    /* max # chars to read */
  177. {
  178.     char iChar();
  179.     char c;
  180.     int  i;
  181.  
  182.     outFlag = OUTOK;
  183.  
  184.     if(strLen(prompt) > 0) {
  185.     doCR();
  186.     mPrintf("Enter %s\n : ", prompt, lim);
  187.     }
  188.  
  189.     i    = 0;
  190.     while (
  191.      c = iChar(),
  192.  
  193.      c      != NEWLINE
  194.      && i      <  lim
  195.      && (haveCarrier || onConsole)
  196.     ) {
  197.     outFlag = OUTOK;
  198.  
  199.     /* handle delete chars: */
  200.     if (c == BACKSPACE) {
  201.         oChar(' ');
  202.         oChar(BACKSPACE);
  203.         if (i > 0) i--;
  204.         else  {
  205.         oChar(' ');
  206.         oChar(BELL);
  207.         }
  208.     } else     buf[i++] = c;
  209.  
  210.     if (i >= lim) {
  211.         oChar(BELL);
  212.         oChar(BACKSPACE); i--;
  213.     }
  214.  
  215.     /* kludge to return immediately on single '?': */
  216.     if (*buf == '?')   {
  217.         doCR();
  218.         break;
  219.     }
  220.     }
  221.     buf[i]  = '\0';
  222. }
  223.  
  224. /************************************************************************/
  225. /*    getText() reads a message from the user             */
  226. /*    Returns TRUE if user decides to save it, else FALSE        */
  227. /************************************************************************/
  228. char getText(prompt, buf, lim, recipient)
  229. char *prompt;
  230. char *buf;
  231. char *recipient;    /* Meaningful iff thisRoom == MAILROOM */
  232. int  lim;    /* max # chars to read */
  233. {
  234.     char iChar(), visible();
  235.     char c, sysopAbort;
  236.     int  i, toReturn;
  237.  
  238.     outFlag = OUTOK;
  239.     if (!expert)    tutorial("entry.blb");
  240.  
  241.     outFlag = OUTOK;
  242.     if (!expert)    mPrintf(   "Enter %s (end with empty line)", prompt);
  243.  
  244.     outFlag = OUTOK;
  245.     doCR();
  246.  
  247.     mPrintf(   "   ");
  248.     printDate();
  249.  
  250.     if (loggedIn)  mPrintf("from %s", msgBuf.mbauth);
  251.     if (thisRoom == MAILROOM) mPrintf(" to %s", recipient);
  252.     doCR();
  253.     lim--;
  254.     i  = 0;
  255.     toReturn    = TRUE;
  256.     sysopAbort    = FALSE;
  257.     do {
  258.     if (whichIO == MODEM)    {
  259.         fastIn(toReturn == ERROR);
  260.         if (whichIO != MODEM)   sysopAbort    = TRUE;
  261.     } else {
  262.        /* this code would handle the modem as well...    */
  263.        /* fastIn() is a later addition to handle people    */
  264.        /* who like to upload fast without handshaking    */
  265.        while (
  266.         !(  (c=iChar()) == NEWLINE   &&   buf[i-1] == NEWLINE )
  267.         && i < lim
  268.         && (haveCarrier || onConsole)
  269.        ) {
  270.            if (debug) putChar(visible(c));
  271.  
  272.            if (c != BACKSPACE)  buf[i++]   = c;
  273.            else {
  274.            /* handle delete chars: */
  275.            oChar(' ');
  276.            oChar(BACKSPACE);
  277.            if (i>0  &&    buf[i-1] != NEWLINE)   i--;
  278.            else                    oChar(BELL);
  279.            }
  280.        }
  281.  
  282.        buf[i] = 0x00;           /* null to terminate message    */
  283.  
  284.        if (i == lim)   mPrintf(" buffer overflow\n ");
  285.     }
  286.     toReturn    =    sysopAbort  ?  FALSE  :  editText(buf, lim);
  287.     } while ((toReturn == ERROR)  &&  (haveCarrier || onConsole));
  288.     return  toReturn;
  289. }
  290.  
  291. /************************************************************************/
  292. /*    getYesNo() prompts for a yes/no response            */
  293. /************************************************************************/
  294. char getYesNo(prompt)
  295. char *prompt;
  296. {
  297.     char iChar(), toUpper();
  298.     int  toReturn;
  299.  
  300.     for (
  301.     doCR(),
  302.     toReturn = ERROR;
  303.  
  304.     toReturn == ERROR   &&     (haveCarrier || onConsole);
  305.     ) {
  306.     outFlag = OUTOK;
  307.     mPrintf("%s? (Y/N): ", prompt);
  308.  
  309.     switch (toUpper(iChar())) {
  310.     case 'Y': toReturn    = TRUE ;        break;
  311.     case 'N': toReturn    = FALSE;        break;
  312.     }
  313.     doCR();
  314.     }
  315.     return   toReturn;
  316. }
  317.  
  318. /************************************************************************/
  319. /*    givePrompt() prints the usual "CURRENTROOM>" prompt.        */
  320. /************************************************************************/
  321. givePrompt() {
  322.     doCR();
  323.  
  324.     if (loggedIn)   printf("(%s)\n", logBuf.lbname);
  325.  
  326.     if (roomBuf.rbflags & CPMDIR)    mPrintf("%s] ", roomBuf.rbname);
  327.     else                mPrintf("%s> ", roomBuf.rbname);
  328. }
  329.  
  330. /************************************************************************/
  331. /*    indexRooms() -- build RAM index to room.buf            */
  332. /************************************************************************/
  333. indexRooms()
  334. {
  335.     int goodRoom, m, roomCount, slot;
  336.  
  337.     roomCount    = 0;
  338.     for (slot=0;  slot<MAXROOMS;  slot++) {
  339.     getRoom(slot);
  340.     if (roomBuf.rbflags & INUSE) {
  341.         roomBuf.rbflags ^=    INUSE;        /* clear "inUse" flag */
  342.         for (m = 0, goodRoom = FALSE; m < MSGSPERRM && !goodRoom; m++)
  343.         {
  344.         /* comparison done with 64K wraparound in mind: */
  345.         if (roomBuf.msg[m].rbmsgNo - oldestLo < 0x800) {
  346.             goodRoom    = TRUE;
  347.         }
  348.         }
  349.         if (goodRoom   ||    (roomBuf.rbflags & PERMROOM))    {
  350.         roomBuf.rbflags |= INUSE;
  351.         }
  352.  
  353.         if (roomBuf.rbflags & INUSE) roomCount++;
  354.         else {
  355.         if (weAre == CITADEL) {
  356.             strCat(msgBuf.mbtext, roomBuf.rbname);
  357.             strCat(msgBuf.mbtext, "> ");
  358.         }
  359.         roomBuf.rbflags = 0;
  360.         putRoom(slot);
  361.         }
  362.     }
  363.     noteRoom();
  364.     }
  365. #ifdef XYZZY
  366.     printf(" %d of %d rooms in use\n", roomCount, MAXROOMS);
  367. #endif
  368. }
  369.  
  370. /************************************************************************/
  371. /*    makeRoom() constructs a new room via dialogue with user.    */
  372. /************************************************************************/
  373. makeRoom() {
  374.     char getYesNo();
  375.     char *nm[NAMESIZE];
  376.     char *oldName[NAMESIZE];
  377.     int  i;
  378.  
  379.     /* update lastMessage for current room: */
  380.     logBuf.lbgen[thisRoom]    = roomBuf.rbgen << GENSHIFT;
  381.  
  382.     strcpy(oldName, roomBuf.rbname);
  383.     if ((thisRoom=findRoom()) == ERROR) {
  384.     indexRooms();    /* try and reclaim an empty room    */
  385.     if ((thisRoom=findRoom()) == ERROR) {
  386.         mPrintf(" ?no room");
  387.         /* may have reclaimed old room, so: */
  388.         if (roomExists(oldName) == ERROR)    strcpy(oldName, "Lobby");
  389.         getRoom(roomExists(oldName));
  390.         return;
  391.     }
  392.     }
  393.  
  394.     getNormStr("name for new room", nm, NAMESIZE);
  395.     if (strlen(nm) == 0) return ;
  396.     if (roomExists(nm) >= 0) {
  397.     mPrintf(" A '%s' already exists.\n", nm);
  398.     /* may have reclaimed old room, so: */
  399.     if (roomExists(oldName) == ERROR)   strcpy(oldName, "Lobby");
  400.     getRoom(roomExists(oldName));
  401.     return;
  402.     }
  403.     if (!expert)   tutorial("newroom.blb");
  404.  
  405.     roomBuf.rbflags = INUSE;
  406.     if (getYesNo(" Make room public"))     roomBuf.rbflags |= PUBLIC;
  407.  
  408.     mPrintf("'%s', a %s room",
  409.     nm,
  410.     roomBuf.rbflags & PUBLIC  ?  "public"  :  "private"
  411.     );
  412.  
  413.     if(!getYesNo("Install it")) {
  414.     /* may have reclaimed old room, so: */
  415.     if (roomExists(oldName) == ERROR)   strcpy(oldName, "Lobby");
  416.     getRoom(roomExists(oldName));
  417.     return;
  418.     }
  419.  
  420.     strcpy(roomBuf.rbname, nm);
  421.     for (i=0;  i<MSGSPERRM;  i++) {
  422.     roomBuf.msg[i].rbmsgNo     = 0;     /* mark all slots empty */
  423.     roomBuf.msg[i].rbmsgLoc  = ERROR;
  424.     }
  425.     roomBuf.rbgen = (roomTab[thisRoom].rtgen + 1) % MAXGEN;
  426.  
  427.     noteRoom();             /* index new room    */
  428.     putRoom(thisRoom);
  429.  
  430.     /* update logBuf: */
  431.     logBuf.lbgen[thisRoom]    = roomBuf.rbgen << GENSHIFT;
  432.     sprintf(msgBuf.mbtext, "%s> created by %s", nm, logBuf.lbname);
  433.     aideMessage(FALSE);
  434. }
  435.  
  436. /************************************************************************/
  437. /*    matchString() searches for match to given string.  Runs backward*/
  438. /*    through buffer so we get most recent error first.        */
  439. /*    Returns loc of match, else ERROR                */
  440. /************************************************************************/
  441. char *matchString(buf, pattern, bufEnd)
  442. char *buf, *pattern, *bufEnd;
  443. {
  444.     char *loc, *pc1, *pc2;
  445.     char foundIt;
  446.  
  447.     for (loc = bufEnd, foundIt = FALSE;  !foundIt && --loc >= buf;) {
  448.     for (pc1 = pattern, pc2 = loc,    foundIt = TRUE ;  *pc1 && foundIt;) {
  449.         if (! (toLower(*pc1++) == toLower(*pc2++)))   foundIt = FALSE;
  450.     }
  451.     }
  452.  
  453.     return   foundIt  ?  loc  :  ERROR;
  454. }
  455.  
  456. /************************************************************************/
  457. /*    getNormStr() gets a string and deletes leading            */
  458. /*                      & trailing blanks etc.    */
  459. /************************************************************************/
  460. getNormStr(prompt, s, size)
  461. char *s, *prompt;
  462. int  size;
  463. {
  464.     char *pc;
  465.  
  466.     getString(prompt, s, size);
  467.     pc = s;
  468.  
  469.     /* find end of string   */
  470.     while (*pc)   {
  471.     if (*pc < ' ')     *pc = ' ';   /* zap tabs etc... */
  472.     pc++;
  473.     }
  474.  
  475.     /* no trailing spaces: */
  476.     while (pc>s  &&  isSpace(*(pc-1))) pc--;
  477.     *pc = '\0';
  478.  
  479.     /* no leading spaces: */
  480.     while (*s == ' ') {
  481.     for (pc=s;  *pc;  pc++)    *pc = *(pc+1);
  482.     }
  483.  
  484.     /* no double blanks */
  485.     for (;  *s;  s++)    {
  486.     if (*s == ' '    &&   *(s+1) == ' ')   {
  487.         for (pc=s;    *pc;  pc++)    *pc = *(pc+1);
  488.     }
  489.     }
  490. }
  491.  
  492. /************************************************************************/
  493. /*    noteRoom() -- enter room into RAM index array.            */
  494. /************************************************************************/
  495. noteRoom()
  496. {
  497.     int i, last;
  498.  
  499.     last = 0;
  500.     for (i=0;  i<MSGSPERROOM;  i++)  {
  501.     if (roomBuf.msg[i].rbmsgNo > last) {
  502.         last = roomBuf.msg[i].rbmsgNo;
  503.     }
  504.     }
  505.     roomTab[thisRoom].rtlastMessage = last         ;
  506.     strcpy(roomTab[thisRoom].rtname, roomBuf.rbname) ;
  507.     roomTab[thisRoom].rtgen        = roomBuf.rbgen  ;
  508.     roomTab[thisRoom].rtflags        = roomBuf.rbflags;
  509. }
  510.  
  511. /************************************************************************/
  512. /*    putRoom() stores room in buf into slot rm in ctdlroom.sys    */
  513. /************************************************************************/
  514. putRoom(rm)
  515. int rm;
  516. {
  517.     int      write();
  518.     unsigned val;
  519.  
  520.     crypte(&roomBuf, (SECSPERROMM * SECTSIZE), rm);
  521.  
  522.     seek(roomfl, rm*SECSPERROOM, 0);
  523.     if ((val = write(roomfl, &roomBuf, SECSPERROOM)) != SECSPERROOM) {
  524.     printf("?putRoom()%d", val);
  525.     }
  526.  
  527.     crypte(&roomBuf, (SECSPERROMM * SECTSIZE), rm);
  528. }
  529.  
  530. /************************************************************************/
  531. /*    renameRoom() is sysop special fn                */
  532. /*    Returns:    TRUE on success else FALSE            */
  533. /************************************************************************/
  534. renameRoom() {
  535.     char getYesNo(), toUpper();
  536.     char nm[NAMESIZE];
  537.     char c, goodOne, wasDirectory;
  538.     int  r;
  539.  
  540.     if (                /* clearer than "thisRoom <= AIDEROOM"*/
  541.     thisRoom == LOBBY
  542.     ||
  543.     thisRoom == MAILROOM
  544.     ||
  545.     thisRoom == AIDEROOM
  546.     ) {
  547.     mPrintf("? -- may not edit this room.\n ");
  548.     return FALSE;
  549.     }
  550.  
  551.     if (!getYesNo("confirm"))    return FALSE;
  552.  
  553.     if (getYesNo("Change name"))   {
  554.     getNormStr("new room name", nm, NAMESIZE);
  555.     r = roomExists(nm);
  556.     if (r>=0  &&  r!=thisRoom) {
  557.          mPrintf("A %s exists already!\n", nm);
  558.     } else {
  559.         strcpy(roomBuf.rbname, nm);   /* also in room itself  */
  560.     }
  561.     }
  562.     mPrintf("%s, ", roomBuf.rbflags & PUBLIC ? "public" : "private");
  563.     mPrintf(
  564.     "%s, ",
  565.     (
  566.         (roomBuf.rbflags & PERMROOM)
  567.         ?
  568.         " permanent"
  569.         :
  570.         " temporary"
  571.     )
  572.     );
  573.     wasDirectory = roomBuf.rbflags & CPMDIR;
  574.     mPrintf("%sdirectory room\n ", wasDirectory  ?  "" : "non");
  575.  
  576.     roomBuf.rbflags = INUSE;
  577.  
  578.     if (getYesNo("Public room"))    {
  579.     roomBuf.rbflags |= PUBLIC;
  580.     } else {
  581.     if (getYesNo("Cause past non-aide users to forget this room"))
  582.         roomBuf.rbgen    = (roomBuf.rbgen +1) % MAXGEN;
  583.     }
  584.  
  585.     if (!onConsole)   roomBuf.rbflags |= wasDirectory;
  586.     else if (getYesNo("Directory room")) {
  587.     roomBuf.rbflags    |= CPMDIR;
  588.  
  589.     printf(" now space %c%c\n", 'A'+roomBuf.rbdisk, '0'+roomBuf.rbuser);
  590.  
  591.     for (goodOne = FALSE;  !goodOne;  )   {
  592.         getString("disk", nm, NAMESIZE);
  593.         c        = toUpper(nm[0]);
  594.         if (c>='A'    && c<='P') {
  595.         roomBuf.rbdisk        = c - 'A';
  596.         goodOne         = TRUE;
  597.         } else mPrintf("?");
  598.     }
  599.  
  600.     roomBuf.rbuser = getNumber("user", 0, 31);
  601.     printf(" space %c%c\n", 'A'+roomBuf.rbdisk, '0'+roomBuf.rbuser);
  602.     }
  603.  
  604.  
  605.     if (
  606.     roomBuf.rbflags & CPMDIR
  607.     ||
  608.     getYesNo("permanent")
  609.     ) {
  610.     roomBuf.rbflags    |= PERMROOM;
  611.     }
  612.  
  613.     noteRoom();
  614.     putRoom(thisRoom);
  615.  
  616.     return TRUE;
  617. }
  618.  
  619. /************************************************************************/
  620. /*    replaceString() corrects typos in message entry         */
  621. /************************************************************************/
  622. replaceString(buf, lim)
  623. char *buf;
  624. int  lim;
  625. {
  626.     char oldString[2*SECTSIZE];
  627.     char newString[2*SECTSIZE];
  628.     char *loc, *textEnd;
  629.     char *pc;
  630.     int  incr;
  631.  
  632.     for (textEnd=buf;  *textEnd;  textEnd++);    /* find terminal null    */
  633.  
  634.     getString("string",      oldString, (2*SECTSIZE));
  635.     if ((loc=matchString(buf, oldString, textEnd)) == ERROR) {
  636.     mPrintf("?not found.\n ");
  637.     return;
  638.     }
  639.  
  640.     getString("replacement", newString, (2*SECTSIZE));
  641.     if ( (strLen(newString)-strLen(oldString))    >=  (&buf[lim]-textEnd) ) {
  642.     mPrintf("?Overflow!\n ");
  643.     return;
  644.     }
  645.  
  646.     /* delete old string: */
  647.     for (pc=loc, incr=strLen(oldString);  *pc=*(pc+incr);  pc++);
  648.     textEnd -= incr;
  649.  
  650.     /* make room for new string: */
  651.     for (pc=textEnd, incr=strLen(newString);  pc>=loc;    pc--) {
  652.     *(pc+incr) = *pc;
  653.     }
  654.  
  655.     /* insert new string: */
  656.     for (pc=newString;    *pc;  *loc++ = *pc++);
  657. }
  658.  
  659. /************************************************************************/
  660. /*    zapRoomFile() erases and re-initilizes room.buf         */
  661. /************************************************************************/
  662. zapRoomFile()
  663. {
  664.     char getCh(), toUpper();
  665.     int i;
  666.  
  667.     printf("\nWipe room file? ");
  668.     if (toUpper(getCh()) != 'Y') return;
  669.  
  670.     roomBuf.rbflags    = 0;
  671.     roomBuf.rbgen    = 0;
  672.     roomBuf.rbdisk    = 0;
  673.     roomBuf.rbuser    = 0;
  674.     roomBuf.rbname[0]    = 0;    /* unnecessary -- but I like it...    */
  675.     for (i=0;  i<MSGSPERRM;  i++) {
  676.     roomBuf.msg[i].rbmsgNo = roomBuf.msg[i].rbmsgLoc = 0;
  677.     }
  678.  
  679.     printf("maxrooms=%d\n", MAXROOMS);
  680.  
  681.     for (i=0;  i<MAXROOMS;  i++) {
  682.     printf("clearing room %d\n", i);
  683.     putRoom(i);
  684.     }
  685.  
  686.     /* Lobby> always exists -- guarantees us a place to stand! */
  687.     thisRoom        = 0        ;
  688.     strcpy(roomBuf.rbname, "Lobby")    ;
  689.     roomBuf.rbflags    = (PERMROOM | PUBLIC | INUSE);
  690.     putRoom(LOBBY);
  691.  
  692.     /* Mail> is also permanent...    */
  693.     thisRoom        = MAILROOM    ;
  694.     strcpy(roomBuf.rbname, "Mail")    ;
  695.     roomBuf.rbflags    = (PERMROOM | PUBLIC | INUSE);
  696.     putRoom(MAILROOM);
  697.  
  698.     /* Aide> also...            */
  699.     thisRoom        = AIDEROOM    ;
  700.     strcpy(roomBuf.rbname, "Aide")    ;
  701.     roomBuf.rbflags    = (PERMROOM | INUSE);
  702.     putRoom(AIDEROOM);
  703. }
  704. tf("\nWipe room file? ");
  705.     if (toUpper(getCh()) != 'Y'